#include "Share.h"

DataBlock::DataBlock( size_t size, Allocator *allocator )
	: allocator_( allocator )
	, base_( 0 )
	, rd_ptr_( 0 )
	, wr_ptr_( 0 )
	, size_( 0 )
{
	if( size != 0 )
	{
		if( !allocator_ )
			allocator_ = Singleton<Allocator>::instance( );

		this->base_ = ( char* ) allocator_->alloc( size );
		size_ = size;
		rd_ptr_ = base_;
		wr_ptr_ = base_;
	}
}

DataBlock::~DataBlock( void )
{
	if( this->base_ )
	{
		allocator_->free( base_ );
	}
}

char* DataBlock::rd_ptr( ) const
{
	return this->rd_ptr_;
}

char* DataBlock::wr_ptr( ) const
{
	return this->wr_ptr_;
}

void DataBlock::rd_ptr( size_t n )
{
	this->rd_ptr_ += n;
}
void DataBlock::wr_ptr( size_t n )
{
	this->wr_ptr_ += n;
}

size_t DataBlock::length( ) const
{
	return ( this->wr_ptr_ - this->rd_ptr_ );
}

size_t DataBlock::size( ) const
{
	return this->size_;
}

size_t DataBlock::space( ) const
{
	return ( this->base_ + this->size_ -  this->wr_ptr_ );
}

int DataBlock::copy( const char* buf, size_t len )
{
	if( len > this->space( ) )
		return -1;

	memcpy( this->wr_ptr_, buf, len );

	this->wr_ptr_ += len;

	return 0;
}

int DataBlock::crunch( )
{
	size_t len = this->wr_ptr_ - this->rd_ptr_;

	memmove( base_, rd_ptr_, len );
	this->rd_ptr_ = base_;
	this->wr_ptr_ = base_ + len;
	return 0;
}

int DataBlock::resize( size_t size )
{
	if( size > this->size_ )
	{
		size_t len = this->length( );
		char *newbuf = ( char* ) allocator_->alloc( size );

		memcpy( newbuf, this->rd_ptr_, len );
		allocator_->free( base_ );
		this->base_ = newbuf;
		this->rd_ptr_ = base_;
		this->wr_ptr_ = this->rd_ptr_ + len;
		this->size_ = size;
	}

	return 0;
}